package com.eugene.shiftscalendar;

import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.preference.PreferenceManager;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Eugene on 01.05.14.
 */
public class PaperPainter extends BasePainter{

    public PaperPainter(WidgetSizes sizes)
    {
        super(sizes);
    }

    int mainLayout()
    {
        return R.layout.paper;
    }

    protected Point getSize(WidgetSizes.WidgetType type)
    {
        return _sizes.getSize(type, 7);
    }

    protected void paintTitle(Canvas canvas, Calendar cal)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Title);
        int szX = sizes.x;
        int szY = sizes.y;
        int shadow = getSize(WidgetSizes.WidgetType.LeftSide).x/2;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(shadow,0,szX,szY), grad);

        // text
        Typeface flow = Typeface.createFromAsset(_context.getAssets(), "fonts/beer_money.ttf");
        Paint textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setSubpixelText(true);
        textPaint.setColor(Color.argb(255, 20, 40, 160));
        textPaint.setTypeface(flow);
        textPaint.setTextSize(szY * 8 / 9);
        //textPaint.setUnderlineText(true);
        Rect bounds = new Rect();
        textPaint.getTextBounds("M",0,1,bounds);
        String[] months = {"Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"};
        int month = cal.get(Calendar.MONTH);
        int year = cal.get(Calendar.YEAR);
        canvas.drawText(months[month]+" "+year, szY/4*3/2, szY/2 + bounds.height()/2, textPaint);

        // shadow
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(0, 0, shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(0,0,shadow,szY,shPaint);
    }

    protected void paintPrev(Canvas canvas)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Prev);
        int szX = sizes.x;
        int szY = sizes.y;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(0,0,szX,szY), grad);

        // Image
        int heightPercent = 50;
        Bitmap arrow = BitmapFactory.decodeResource(_context.getResources(), R.drawable.prev_month_sketch);
        int heightNew = szY*heightPercent/100;
        double scale = (double)arrow.getHeight() / heightNew;
        int widthNew = (int)(arrow.getWidth()/scale);
        canvas.drawBitmap(arrow,new Rect(0,0,arrow.getWidth(),arrow.getHeight()),
                new Rect(szX/2-widthNew/2,(50-heightPercent/2)*szY/100,szX/2+widthNew/2,(50+heightPercent/2)*szY/100),
                new Paint(Paint.FILTER_BITMAP_FLAG + Paint.ANTI_ALIAS_FLAG + Paint.DITHER_FLAG));
    }

    protected void paintNext(Canvas canvas)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Next);
        int szX = sizes.x;
        int szY = sizes.y;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(0,0,szX,szY), grad);

        // Image
        int heightPercent = 50;
        Bitmap arrow = BitmapFactory.decodeResource(_context.getResources(),R.drawable.next_month_sketch);
        int heightNew = szY*heightPercent/100;
        double scale = (double)arrow.getHeight() / heightNew;
        int widthNew = (int)(arrow.getWidth()/scale);
        canvas.drawBitmap(arrow,new Rect(0,0,arrow.getWidth(),arrow.getHeight()),
                new Rect(szX/2-widthNew/2,(50-heightPercent/2)*szY/100,szX/2+widthNew/2,(50+heightPercent/2)*szY/100),
                new Paint(Paint.FILTER_BITMAP_FLAG + Paint.ANTI_ALIAS_FLAG + Paint.DITHER_FLAG));
    }

    protected void paintSettings(Canvas canvas)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Settings);
        int szX = sizes.x;
        int szY = sizes.y;
        int shadow = getSize(WidgetSizes.WidgetType.LeftSide).x/2;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(0,0,szX-shadow,szY), grad);

        // Image
        int heightPercent = 50;
        Bitmap arrow = BitmapFactory.decodeResource(_context.getResources(),R.drawable.settings_sketch);
        int heightNew = szY*heightPercent/100;
        double scale = (double)arrow.getHeight() / heightNew;
        int widthNew = (int)(arrow.getWidth()/scale);
        canvas.drawBitmap(arrow,new Rect(0,0,arrow.getWidth(),arrow.getHeight()),
                new Rect(szX/2-widthNew/2,(50-heightPercent/2)*szY/100,szX/2+widthNew/2,(50+heightPercent/2)*szY/100),
                new Paint(Paint.FILTER_BITMAP_FLAG + Paint.ANTI_ALIAS_FLAG + Paint.DITHER_FLAG));

        // shadow
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(szX, 0, szX-shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(szX-shadow,0,szX,szY,shPaint);
    }

    protected void paintWeeks(Canvas canvas)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Weeks);
        int szX = sizes.x;
        int szY = sizes.y;
        int shadow = getSize(WidgetSizes.WidgetType.LeftSide).x/2;
        //init
        int YOffset = 5;
        int LeftOffset = getSize(WidgetSizes.WidgetType.LeftSide).x;
        int RightOffset = getSize(WidgetSizes.WidgetType.RightSide).x;
        int XSize = szX - LeftOffset - RightOffset;
        String days[] = {"пн", "вт", "ср", "чт", "пт", "сб", "вс"};

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(shadow,0,szX-shadow,szY), grad);

        // circles
        /*int rad = szY/15;
        Paint circ = new Paint();
        circ.setAntiAlias(true);
        circ.setColor(Color.argb(255,140,140,140));
        for(int i=0;i<szX/(rad*1.5);i++){
            canvas.drawCircle((float)((i+1)*rad+i*rad*1.5),rad,rad,circ);
        }*/

        // line
        Paint line = new Paint();
        line.setColor(Color.argb(140,255,85,85));
        canvas.drawRect(shadow,szY-4,szX-shadow,szY,line);
        line.setColor(Color.argb(255,255,85,85));
        canvas.drawRect(shadow,szY-2,szX-shadow,szY-1,line);

        // text
        Typeface flow = Typeface.createFromAsset(_context.getAssets(), "fonts/beer_money.ttf");
        Paint textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setSubpixelText(true);
        textPaint.setColor(Color.argb(230,30,30,30));
        textPaint.setTextSize(szY-YOffset);
        textPaint.setTypeface(flow);
        Rect bounds = new Rect();
        textPaint.getTextBounds("M",0,1,bounds);
        for(int i=0;i<7;i++){
            canvas.drawText(days[i], LeftOffset + XSize/14 + i*XSize/7 - textPaint.measureText(days[i])/2, szY/2+bounds.height()/2, textPaint);
        }

        // shadow
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(0, 0, shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(0, 0, shadow, szY, shPaint);
        shPaint.setShader(new LinearGradient(szX, 0, szX-shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(szX-shadow,0,szX,szY,shPaint);
    }

    protected void paintDay(Canvas canvas, Calendar cal)
    {
        Point sizes = getSize(WidgetSizes.WidgetType.Day);
        int szX = sizes.x;
        int szY = sizes.y;

        // today
        Calendar todayCal = Calendar.getInstance();
        boolean today = todayCal.get(Calendar.YEAR) == cal.get(Calendar.YEAR) && todayCal.get(Calendar.MONTH) == cal.get(Calendar.MONTH) &&
                todayCal.get(Calendar.DAY_OF_MONTH) == cal.get(Calendar.DAY_OF_MONTH);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(_context);
        int month = sp.getInt("CurrMonth",cal.get(Calendar.MONTH));

        // background
        Paint line = new Paint();
        line.setAntiAlias(true);
        //line.setColor(today && cal.get(Calendar.MONTH) == month ? Color.argb(255,200,200,200) : Color.argb(170,200,200,200));
        //if(today && cal.get(Calendar.MONTH) == month) line.setStrokeWidth(5);
        canvas.drawColor(Color.argb(255, 255, 246, 213));

        line.setColor(Color.argb(140,95,141,211));
        canvas.drawLine(0,0,0,szY,line);
        line.setColor(Color.argb(255,95,141,211));
        canvas.drawLine(szX,szY,szX,0,line);
        //canvas.drawLine(0,szY,szX,szY,line);
        //canvas.drawLine(szX,0,0,0,line);

        if(today && cal.get(Calendar.MONTH) == month){
            Bitmap marker = BitmapFactory.decodeResource(_context.getResources(),R.drawable.marker3);
            int widthNew = szX;
            double scale = (double)marker.getWidth() / widthNew * 0.8;
            int heightNew = (int)(marker.getHeight()/scale);
            canvas.drawBitmap(marker,new Rect(0,0,marker.getWidth(),marker.getHeight()),
                    new Rect(szX/2-widthNew/2,szY/2-heightNew/2,szX/2+widthNew/2,szY/2+heightNew/2),
                    new Paint(Paint.FILTER_BITMAP_FLAG + Paint.ANTI_ALIAS_FLAG + Paint.DITHER_FLAG));
        }

        // text
        Typeface flow = Typeface.createFromAsset(_context.getAssets(), "fonts/beer_money.ttf");
        Paint textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setSubpixelText(true);
        if(cal.get(Calendar.MONTH) != month){
            textPaint.setColor(_dateType.isHoliday(cal,_context) ? Color.argb(120, 0,0,0) : Color.argb(120, 0,0,0));
        }
        else{
            textPaint.setColor(_dateType.isHoliday(cal,_context) ? Color.argb(240, 200, 42, 22) : Color.argb(240, 0,0,0));
        }
        textPaint.setTextSize(szY*2/3);
        textPaint.setTypeface(flow);
        Rect bounds = new Rect();
        String text = "" + cal.get(Calendar.DAY_OF_MONTH);
        textPaint.getTextBounds(text,0,text.length(), bounds);
        canvas.drawText(text, szX/2 - bounds.width()/2, szY/2 + bounds.height()/2, textPaint);

        if(_dateType.isUserChanged(cal, _context) && cal.get(Calendar.MONTH) == month){
            Paint grad = new Paint();
            grad.setAntiAlias(true);
            grad.setSubpixelText(true);
            grad.setColor(Color.argb(200, 30,30,30));
            grad.setTextSize(szY*0.3f);
            grad.setTypeface(flow);
            bounds = new Rect();
            text = "*";
            textPaint.getTextBounds(text,0,text.length(), bounds);
            canvas.drawText(text, szX - bounds.width()*2/3, bounds.height(), grad);
        }
    }

    protected void paintFooter(Canvas canvas){
        Point sizes = getSize(WidgetSizes.WidgetType.Footer);
        int szX = sizes.x;
        int szY = sizes.y;
        int shadow = getSize(WidgetSizes.WidgetType.LeftSide).x/2;
        int fsize = szY/4;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        canvas.drawRect(new Rect(shadow,0,szX-shadow,fsize), grad);

        // add shadows
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(0, 0, shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(0,0,shadow,fsize,shPaint);
        shPaint.setShader(new LinearGradient(szX, 0, szX-shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(szX - shadow, 0, szX, fsize, shPaint);

        shPaint.setShader(new LinearGradient(0, fsize, 0, fsize + (szY-fsize)/2, Color.argb(120,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        canvas.drawRect(shadow,fsize,szX-shadow,fsize + (szY-fsize)/2,shPaint);

        // shadow circles
        int R = fsize + (szY-fsize)/2;
        shPaint.setShader(new LinearGradient(shadow, fsize, shadow/2, fsize+R/2, Color.argb(80,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        Path p1 = new Path();
        p1.moveTo(0,fsize); p1.lineTo(shadow,fsize);p1.lineTo(shadow,fsize+R);p1.lineTo(0,fsize);
        canvas.drawPath(p1,shPaint);
        shPaint.setShader(new LinearGradient(szX-shadow, fsize, szX-shadow/2, fsize+R/2, Color.argb(80,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        p1.reset();
        p1.moveTo(szX,fsize);p1.lineTo(szX-shadow,fsize);p1.lineTo(szX-shadow,fsize+R);p1.lineTo(szX,fsize);
        canvas.drawPath(p1,shPaint);
    }
    protected void paintLeftSide(Canvas cnv){
        Point sizes = getSize(WidgetSizes.WidgetType.LeftSide);
        int szX = sizes.x;
        int szY = sizes.y;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        cnv.drawRect(new Rect(szX/2,0,szX,szY), grad);

        // line
        Paint line = new Paint();
        line.setColor(Color.argb(140,95,141,211));
        cnv.drawLine(szX-1,0,szX-1,szY,line);

        // shadow
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(0, 0, szX/2, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawRect(0,0,szX/2,szY,shPaint);
    }
    protected void paintRightSide(Canvas cnv){
        Point sizes = getSize(WidgetSizes.WidgetType.RightSide);
        int szX = sizes.x;
        int szY = sizes.y;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setShader(new LinearGradient(0, 0, 0, szY, Color.argb(255, 255, 246, 213), Color.argb(255, 255, 246, 213), Shader.TileMode.MIRROR));
        cnv.drawRect(new Rect(0,0,szX/2+1,szY), grad);

        // line
        Paint line = new Paint();
        line.setColor(Color.argb(140,95,141,211));
        cnv.drawLine(0,0,0,szY,line);

        // shadow
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(szX/2, 0, szX, 0, Color.argb(120,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawRect(szX/2+1,0,szX,szY,shPaint);
    }

    protected void paintUpper(Canvas cnv){
        Point sizes = getSize(WidgetSizes.WidgetType.Upper);
        int szX = sizes.x;
        int szY = sizes.y;
        int shadow = getSize(WidgetSizes.WidgetType.LeftSide).x/2;

        // background
        Paint grad = new Paint();
        grad.setAntiAlias(true);
        grad.setColor(Color.argb(255, 255, 246, 213));

        Path path = new Path();
        path.addRect(shadow,shadow,szX-shadow,szY, Path.Direction.CW);

        cnv.drawPath(path, grad);

        List<Point> centers = new ArrayList();
        Paint eraserPaint = new Paint();
        eraserPaint.setAlpha(0);
        eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        eraserPaint.setAntiAlias(true);
        int rad = szY/4;
        int N = 8;
        int x = (szX-N*2*rad)/(N+2);

        // add circles
        for(int i=0;i<N;i++){
            centers.add(new Point((int) (1.5*x + rad + i*(x+2*rad)), szY / 2 + shadow));
            cnv.drawCircle((float) (1.5*x + rad + i*(x+2*rad)), szY / 2 + shadow, rad, eraserPaint);
        }

        // add circle shadows
        Iterator<Point> iter = centers.iterator();
        while(iter.hasNext()){
            Point item = iter.next();
            Paint gr = new Paint();
            gr.setShader(new RadialGradient(item.x, item.y, rad,
                    new int[]{Color.argb(0, 0, 0, 0), Color.argb(0, 0, 0, 0), Color.argb(100, 0, 0, 0)},
                    new float[]{0, 0.3f, 1}, Shader.TileMode.MIRROR));
            cnv.drawCircle(item.x, item.y, rad, gr);
        }

        // add shadows
        Paint shPaint = new Paint();
        shPaint.setAntiAlias(true);
        shPaint.setShader(new LinearGradient(0, 0, 0, shadow, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawRect(shadow,0,szX-shadow,shadow,shPaint);
        shPaint.setShader(new LinearGradient(0, 0, shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawRect(0,shadow,shadow,szY,shPaint);
        shPaint.setShader(new LinearGradient(szX, 0, szX-shadow, 0, Color.argb(0,0,0,0), Color.argb(120,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawRect(szX-shadow,shadow,szX,szY,shPaint);

        // shadow circles
        shPaint.setShader(new RadialGradient(shadow,shadow,shadow,Color.argb(120,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawArc(new RectF(0,0,2*shadow,2*shadow),-90,-90,true,shPaint);
        shPaint.setShader(new RadialGradient(szX-shadow,shadow,shadow,Color.argb(120,0,0,0), Color.argb(0,0,0,0), Shader.TileMode.MIRROR));
        cnv.drawArc(new RectF(szX-2*shadow,0,szX,2*shadow),-90,90,true,shPaint);
    }
}
